package com.supermarket.manage.provider.stocking.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.supermarket.manage.common.dto.PageBean;
import com.supermarket.manage.common.dto.prod.response.ProductDto;
import com.supermarket.manage.common.dto.stock.request.StockingPageParams;
import com.supermarket.manage.common.dto.stock.response.StockProdDto;
import com.supermarket.manage.common.dto.stock.response.StockingDto;
import com.supermarket.manage.common.pojo.Product;
import com.supermarket.manage.common.pojo.Stocking;
import com.supermarket.manage.common.pojo.StockingProd;
import com.supermarket.manage.common.utils.BigDecimalUtil;
import com.supermarket.manage.provider.api.product.ProductService;
import com.supermarket.manage.provider.api.stocking.StockingService;
import com.supermarket.manage.provider.stocking.mapper.StockingMapper;
import com.supermarket.manage.provider.stocking.mapper.StockingProdMapper;
import com.supermarket.manage.provider.util.IDUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author Faxon
 * @version 1.0
 * @date 2020-03-17 16:57
 **/
@Service(version = "1.0.0")
public class StockingServiceImpl implements StockingService {

    @Resource
    private StockingMapper stockingMapper;

    @Resource
    private StockingProdMapper stockingProdMapper;

    @Resource
    private IDUtil idUtil;

    @Reference(version = "1.0.0")
    private ProductService productService;

    @Override
    public PageBean<Stocking> getStockingPageList(StockingPageParams params) {
        PageHelper.startPage(params.getPage(), params.getSize());
        Page<Stocking> page = stockingMapper.getStockingPageList(params);
        if (page == null) {
            return null;
        }
        return new PageBean<>(page.getPageNum(), page.getPageSize(), page.getResult(), page.getTotal());
    }

    @Override
    public StockingDto getStockingById(String id) {
        Stocking stocking = stockingMapper.selectById(id);
        if (stocking == null) {
            return null;
        }
        StockingDto dto = new StockingDto();
        BeanUtils.copyProperties(stocking, dto);
        //查询入库商品信息
        QueryWrapper<StockingProd> wrapper = new QueryWrapper<>();
        wrapper.eq("stocking_id", id);
        List<StockingProd> stockingProds = stockingProdMapper.selectList(wrapper);
        //将查询结果封装到map中
        Map<String, StockProdDto> map = new HashMap<>(stockingProds.size());
        List<String> ids = new ArrayList<>();
        stockingProds.forEach(i -> {
            ids.add(i.getPid());
            StockProdDto stockProdDto = new StockProdDto();
            stockProdDto.setSid(i.getSid());
            stockProdDto.setStockingId(i.getStockingId());
            stockProdDto.setPid(i.getPid());
            stockProdDto.setPnumber(i.getPnumber());
            stockProdDto.setSubtotal(i.getSubtotal());
            stockProdDto.setGray(Boolean.FALSE);
            map.put(i.getPid(), stockProdDto);
        });
        //获取商品详情
        List<ProductDto> prods = productService.getProdDtoByPids(ids);
        List<StockProdDto> data = new ArrayList<>();
        prods.forEach(p -> {
            StockProdDto stockProdDto = map.get(p.getPid());
            if (stockProdDto != null) {
                stockProdDto.setPname(p.getPname());
                stockProdDto.setUnitName(p.getUnitName());
                stockProdDto.setPic(p.getPic());
                stockProdDto.setCostPrice(p.getCostPrice());
                stockProdDto.setFirstCname(p.getFirstCname());
                stockProdDto.setSecondCname(p.getSecondCname());
                stockProdDto.setThirdCname(p.getThirdCname());
            }
            data.add(stockProdDto);
        });
        dto.setStockingProds(data);
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean doneStockingById(Stocking stocking) {
        //修改关联商品库存
        QueryWrapper<StockingProd> wrapper = new QueryWrapper<>();
        wrapper.eq("stocking_id", stocking.getId());
        List<StockingProd> prodList = stockingProdMapper.selectList(wrapper);
        List<Product> products = new ArrayList<>();
        prodList.forEach(p -> {
            Product product = new Product();
            product.setPid(p.getPid());
            product.setStockNumber(p.getPnumber());
            products.add(product);
        });
        //修正商品库存
        productService.updateStockingNumber(products);
        //修改出库单状态
        stocking.setUpdated(new Date());
        return stockingMapper.updateById(stocking) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteStockingById(String id) {
        QueryWrapper<StockingProd> wrapper = new QueryWrapper<>();
        wrapper.eq("stocking_id", id);
        stockingProdMapper.delete(wrapper);
        stockingMapper.deleteById(id);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addStocking(Stocking stocking) {
        //添加单据
        stocking.setId(idUtil.getStockingId());
        Date date = new Date();
        stocking.setCreated(date);
        stocking.setUpdated(date);
        stockingMapper.insert(stocking);
        //添加关联商品
        List<StockingProd> stockingProds = stocking.getStockingProds();
        stockingProds.forEach(p -> {
            p.setSid(idUtil.getUUID());
            p.setStockingId(stocking.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSnumber(BigDecimalUtil.formatTwoPoint(p.getSnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
        });
        stockingProdMapper.insertList(stockingProds);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStocking(Stocking stocking) {
        //更新单据
        stocking.setUpdated(new Date());
        stockingMapper.updateById(stocking);
        //删除旧的关联商品
        QueryWrapper<StockingProd> wrapper = new QueryWrapper<>();
        wrapper.eq("stocking_id", stocking.getId());
        stockingProdMapper.delete(wrapper);
        //添加关联商品
        List<StockingProd> stockingProds = stocking.getStockingProds();
        stockingProds.forEach(p -> {
            p.setSid(idUtil.getUUID());
            p.setStockingId(stocking.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSnumber(BigDecimalUtil.formatTwoPoint(p.getSnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
        });
        stockingProdMapper.insertList(stockingProds);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addStockingAndUpdateStockingNumber(Stocking stocking) {
        //添加单据
        stocking.setId(idUtil.getStockingId());
        Date date = new Date();
        stocking.setCreated(date);
        stocking.setUpdated(date);
        stockingMapper.insert(stocking);
        //添加关联商品并修正库存
        List<StockingProd> stockingProds = stocking.getStockingProds();
        List<Product> products = new ArrayList<>();
        stockingProds.forEach(p -> {
            p.setSid(idUtil.getUUID());
            p.setStockingId(stocking.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSnumber(BigDecimalUtil.formatTwoPoint(p.getSnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
            Product product = new Product();
            product.setPid(p.getPid());
            product.setStockNumber(p.getPnumber());
            products.add(product);
        });
        stockingProdMapper.insertList(stockingProds);
        productService.updateStockingNumber(products);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStockingAndUpdateStockingNumber(Stocking stocking) {
        //更新单据
        stocking.setUpdated(new Date());
        stockingMapper.updateById(stocking);
        //删除旧的关联商品
        QueryWrapper<StockingProd> wrapper = new QueryWrapper<>();
        wrapper.eq("stocking_id", stocking.getId());
        stockingProdMapper.delete(wrapper);
        //添加关联商品并修正库存
        List<StockingProd> stockingProds = stocking.getStockingProds();
        List<Product> products = new ArrayList<>();
        stockingProds.forEach(p -> {
            p.setSid(idUtil.getUUID());
            p.setStockingId(stocking.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSnumber(BigDecimalUtil.formatTwoPoint(p.getSnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
            Product product = new Product();
            product.setPid(p.getPid());
            product.setStockNumber(p.getPnumber());
            products.add(product);
        });
        stockingProdMapper.insertList(stockingProds);
        productService.updateStockingNumber(products);
        return Boolean.TRUE;
    }

    @Override
    public List<Stocking> getStockingList(StockingPageParams params) {
        return stockingMapper.getStockingList(params);
    }
}
